#ifndef COMMANDS_QUEUE_H_
#define COMMANDS_QUEUE_H_

#include <boost/thread.hpp>
#include <list>
#include "./Command.h"

namespace Commands {

/* Singleton stanowiacy bufor - kolejke fifo dla wszystkich komend ktore powinny zostac odebrane przez
 * watek glowny aplikacji. */
class Queue {
	/* Lista komend: */
	std::list< Command* > commands_;
	/* Mutex strzegacy dostepu do elementow kolejki: */
	boost::mutex mutex_;
public:
	/* Zwraca instancje kolejki.
	 *
	 * UWAGA! Metoda nie jest synchronizowana: nalezy wywolac getInstance() przed
	 *        utworzeniem nowych watkow w celu unikniecia wyscigow.
	 */
	static Queue& getInstance() {
		static Queue instance;
		return instance;
	};

	/* Synchronizowana metoda umieszczajaca element na koncu kolejki: */
	void push( Command* c ) {
		//wchodzimy do sekcji krytycznej:
		boost::mutex::scoped_lock lock( mutex_ );
		commands_.push_back( c );
	};

	/* Synchronizowana metoda zwracajaca pierwszy element w kolejce: */
	Command* pop() {
		//wchodzimy do sekcji krytycznej:
		boost::mutex::scoped_lock lock( mutex_ );
		if( commands_.empty() )
			return 0;
		else {
			Command* c = commands_.front();
			commands_.pop_front();
			return c;
		}
	}

}; //class Queue

} //namespace Commands

#endif /* COMMANDS_QUEUE_H_ */
